package org.example.mine.controller;

import cn.hutool.core.date.DateUtil;
import com.alipay.api.AlipayApiException;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.example.mine.config.AlipayTemplate;
import org.example.mine.service.TopUpService;
import org.example.mine.service.WxPayService;
import org.example.model.common.Result;
import org.example.model.domain.express.ExpressDetial;
import org.example.model.domain.express.ExpressList;
import org.example.model.domain.mine.ExpressExchange;
import org.example.model.domain.mine.ExpressRechargeRecord;
import org.example.model.vo.mine.PayVo;
import org.example.model.vo.mine.TopUpVo;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/topup")
@Slf4j
public class TopUpController {

    @Resource
    public TopUpService topUpService;

    //    获取充值记录
    @GetMapping("/gettopuplist/{registerIp}")
    public TopUpVo getTopUpList(@PathVariable("registerIp") Long registerIp){
        TopUpVo topUpVo = topUpService.selectTopUpList(registerIp);
        return topUpVo;
    }

//    获取充值信息
    @GetMapping("/gettopupmsg/{orderId}")
    public ExpressRechargeRecord gettopupmsg(@PathVariable("orderId") String orderId){
        ExpressRechargeRecord expressRechargeRecord = topUpService.selectorder(orderId);
        return expressRechargeRecord;
    }
    //    根据id查询充值记录
    @GetMapping("/gettopupbyid/{id}")
    public ExpressRechargeRecord gettopupbyid(@PathVariable("id") Long id){
        return topUpService.gettopupbyid(id);
    }

    //    查询汇率信息
    @GetMapping("/getexchange")
    public ExpressExchange getexchange(){
        ExpressExchange exchange = topUpService.getexchange();
        return exchange;
    }

    //    查询汇率信息
    @GetMapping("/topupfail/{id}")
    public Result topupfila(@PathVariable("id") Integer id){
        topUpService.topupfail(id);
        return Result.build(200,"成功");
    }

    @Autowired
    public RabbitTemplate rabbitTemplate;

    //    支付宝支付
    @PostMapping("/addtopup")
    public Result alipay(@RequestBody ExpressRechargeRecord expressRechargeRecord){
        String key = "COURIER:EXPRESS:LOGIN" + expressRechargeRecord.getRegisterIp();
        ExpressList expressListRedis = (ExpressList) redisTemplate.opsForValue().get(key);
        Integer realNameStatus = expressListRedis.getRealNameStatus();
        if(realNameStatus!=1){
            return Result.build(500,"请先实名认证");
        }
        int num=topUpService.addTopupOrder(expressRechargeRecord);
        if(num==0){
            return Result.build(500,"失败");
        }
        rabbitTemplate.convertAndSend("user.order.delay_exchange", "user.order.delay_key", expressRechargeRecord, message -> {
            message.getMessageProperties().setExpiration("900000");
            return message;
        });
        topUpService.addPayOrder(expressRechargeRecord);
        return Result.build(200, "成功", expressRechargeRecord.getId());
    }

    @GetMapping("getexpressdetail/{id}")
    public ExpressDetial getexpressdetail(@PathVariable("id") String id){
        return topUpService.getexpressdetail(id);
    }


//    取消订单
    @GetMapping("cancelpay/{id}")
    public Result cancelpay(@PathVariable("id") Integer id){
        topUpService.topupfila(id);
        return Result.build(200,"成功");
    }

    @Resource
    AlipayTemplate alipayTemplate;
    @GetMapping(value = "/alipay/{id}", produces = "text/html")
    @ResponseBody
    public String pay(@PathVariable("id") long id) throws AlipayApiException {
        ExpressRechargeRecord expressRechargeRecord = topUpService.gettopupbyid(id);
        return alipayTemplate.pay(expressRechargeRecord);
    }

    @Autowired
    public RedisTemplate redisTemplate;
    @PostMapping("/notify")  // 注意这里必须是POST接口
    public String payNotify(HttpServletRequest request) throws Exception {
        if (request.getParameter("trade_status").equals("TRADE_SUCCESS")) {
            Map<String, String> params = new HashMap<>();
            Map<String, String[]> requestParams = request.getParameterMap();
            for (String name : requestParams.keySet()) {
                params.put(name, request.getParameter(name));
            }

            String tradeNo = params.get("out_trade_no");
            String gmtPayment = params.get("gmt_payment");
            String alipayTradeNo = params.get("trade_no");
            // 支付宝验签
            ExpressDetial expressDetial = (ExpressDetial) redisTemplate.boundValueOps(params.get("out_trade_no")).get();
            redisTemplate.delete(params.get("out_trade_no"));
            // 更新订单状态
            ExpressRechargeRecord expressRechargeRecord1 = topUpService.selectorder(params.get("out_trade_no"));
            if(expressRechargeRecord1.getStatus()==4){
                log.info("订单已关闭，支付无效");
            }else{
            ExpressRechargeRecord expressRechargeRecord = new ExpressRechargeRecord();
            expressRechargeRecord.setTransactionNumber(params.get("out_trade_no"));
            expressRechargeRecord.setOverTime(new Date());
            expressRechargeRecord.setFuTime(DateUtil.parse(params.get("gmt_payment"),"yyyy-MM-dd HH:mm:ss"));
            expressRechargeRecord.setClosingTime(new Date());
            expressRechargeRecord.setStatus(3);
            topUpService.alipaycallback(expressRechargeRecord);
            topUpService.updateUserBalance(expressDetial);
            }
        }
        return "success";
    }


    @Autowired
    WxPayService wxPayService;
    //    微信支付
    @PostMapping("/subWx/{id}")
    public PayVo subWxOrder(@PathVariable("id") Long id) throws Exception {
        ExpressRechargeRecord expressRechargeRecord = topUpService.gettopupbyid(id);

        ExpressDetial expressDetial = new ExpressDetial();
        expressDetial.setRegisterIp(Long.valueOf(expressRechargeRecord.getRegisterIp()));
        expressDetial.setAccountBalance(BigDecimal.valueOf(new BigDecimal(expressRechargeRecord.getBalanceAfterRecharging()).doubleValue()));
        redisTemplate.boundValueOps(expressRechargeRecord.getTransactionNumber()).set(expressDetial,60*15, TimeUnit.SECONDS);
        //1.从数据库查询(订单名称,订单编号,订单金额)
        String body = "余额充值";    //订单名称(商品名称)
        String orderId = expressRechargeRecord.getTransactionNumber();   //订单编号
        String money = "1";         //订单金额(分)
        //3.调用微信工具类,把订单发给微信
        Map<String, String> payMap = wxPayService.createNative(body, orderId, money);
        log.info("下单结果:" + payMap);
        if (payMap == null) {
            throw new RuntimeException("下单失败,请稍后重试!");
        }
        //4.判断下单是否正常
        String return_code = payMap.get("return_code");
        if (!return_code.equals("SUCCESS")) {
            //获取错误信息
            String return_msg = payMap.get("return_msg");
            throw new RuntimeException(return_msg);
        }
        PayVo payVo = new PayVo();
        //5.如果成功,则获取生成的支付Url
        String code_url = payMap.get("code_url");
        redisTemplate.boundValueOps(id.toString()).set(code_url,60*15, TimeUnit.SECONDS);
        if(code_url == null){
            payVo.setUrl((String) redisTemplate.boundValueOps(id.toString()).get());
        }
        payVo.setUrl(code_url);
        payVo.setOrderId(orderId);
        return payVo;
    }


    //    订单监控
    @PostMapping("/checkWx/{orderId}")
    public String checkWxOrder(@PathVariable("orderId") String orderId) throws Exception {
        //1.根据订单号,去微信中,查询订单状态
        Map<String, String> checkMap = wxPayService.queryNative(orderId);
        //2.获取请求结果
        String return_code = checkMap.get("return_code");
        ExpressRechargeRecord selectorder = topUpService.selectorder(orderId);
        ExpressDetial expressDetial = (ExpressDetial) redisTemplate.boundValueOps(selectorder.getTransactionNumber()).get();
        log.info("查询结果:" + expressDetial);

        if (return_code.equals("SUCCESS")) {
            //3.获取订单状态
            String trade_state = checkMap.get("trade_state");
            if (trade_state.equals("SUCCESS")) {
                // 订单已经支付
                redisTemplate.delete(selectorder.getId().toString());
                ExpressRechargeRecord expressRechargeRecord = new ExpressRechargeRecord();
                expressRechargeRecord.setTransactionNumber(selectorder.getTransactionNumber());
                expressRechargeRecord.setOverTime(new Date());
                expressRechargeRecord.setFuTime(new Date());
                expressRechargeRecord.setClosingTime(new Date());
                expressRechargeRecord.setStatus(3);
                topUpService.alipaycallback(expressRechargeRecord);
                topUpService.updateUserBalance(expressDetial);
                redisTemplate.delete(selectorder.getTransactionNumber());
                // 修改订单状态(修改数据库中的订单状态)
            } else if (trade_state.equals("PAYERROR")) {
                // 支付失败!
                topUpService.topupfail(selectorder.getId());
                // 修改订单状态(修改数据库中的订单状态);
            } else if (trade_state.equals("CLOSED")) {
                // 订单超时,已关闭!
                topUpService.topupfila(selectorder.getId());
                // 修改订单状态(修改数据库中的订单状态);
            } else if (trade_state.equals("NOTPAY")) {
                // 未支付!
            } else if (trade_state.equals("USERPAYING")) {
                // 支付中!
            } else if (trade_state.equals("REFUND")) {
                // 已取消
            }
            return trade_state;
        } else {
            // 获取请求失败原因
            String return_msg = checkMap.get("return_msg");
            throw new RuntimeException(return_msg);
        }
    }


    //    关闭订单
    @RequestMapping("/closeWx")
    public String closeWxOrder(String orderId) throws Exception {
        //1.根据订单号,去微信中,关闭订单
        Map<String, String> map = wxPayService.closeNative(orderId);
        //2.获取请求结果
        String return_code = map.get("return_code");
        if (return_code.equals("SUCCESS")) {
            //3.获取关闭结果
            String result_code = map.get("result_code");
            if (result_code.equals("SUCCESS")) {
                // 关闭成功
                return "SUCCESS";
            } else {
                // 获取错误原因
                String err_code_des = map.get("err_code_des");
                throw new RuntimeException(err_code_des);
            }
        } else {
            //4. 获取请求失败原因
            String return_msg = map.get("return_msg");
            throw new RuntimeException(return_msg);
        }
    }
}
